/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package com.huawei.rpc.server;

import com.huawei.rpc.common.prorocol.MessageProtocol;
import com.huawei.rpc.common.prorocol.Request;
import com.huawei.rpc.common.prorocol.Response;
import com.huawei.rpc.common.prorocol.Status;
import com.huawei.rpc.server.register.ServiceObject;
import com.huawei.rpc.server.register.ServiceRegister;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author Lijl
 * @ClassName RequestHandler
 * @Description 请求处理器，提供解组请求，编组响应操作
 * @Date 2022/2/15 16:10
 * @Version 1.0
 */
public class RequestHandler {
    private MessageProtocol protocol;

    private ServiceRegister serviceRegister;

    public RequestHandler(MessageProtocol protocol,ServiceRegister serviceRegister){
        super();
        this.protocol = protocol;
        this.serviceRegister = serviceRegister;
    }

    /**
     * @Author lijl
     * @MethodName handleRequest
     * @Description 处理客户端请求参数，调用本地服务
     * @Date 16:26 2022/2/15
     * @Version 1.0
     * @param data
     * @return: byte[]
    **/
    public byte[] handleRequest(byte[] data) throws Exception{
        //1.解组消息
        Request request = this.protocol.unmarshallingRequest(data);
        //2. 查找服务对象
        ServiceObject so = this.serviceRegister.getServiceObject(request.getServiceName());

        Response response = null;
        if (so==null){
            response = Response.builder().status(Status.NOT_FOUND).build();
        }else{
            try {
                //3.反射调用对应的过程方法
                Method method = so.getClazz().getMethod(request.getMethod(), request.getParameterTypes());
                Object returnVal = method.invoke(so.getObj(), request.getParameters());
                response = Response.builder()
                        .status(Status.SUCCESS)
                        .returnValue(returnVal)
                        .build();
            } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException |
                    InvocationTargetException e) {
                response = Response.builder()
                        .status(Status.ERROR)
                        .exception(e)
                        .build();
            }
        }
        return this.protocol.marshallingResponse(response);
    }
}
